﻿using Compass.Wasm.Shared.Purchases;
using Compass.Wpf.ApiServices.Purchases;
using Microsoft.Win32;
using OfficeOpenXml;
using System.Collections.Generic;
using Compass.Wasm.Shared.Extensions;
using Compass.Wpf.Views.Purchases;

namespace Compass.Wpf.ViewModels.Purchases;

public class NavInvValuationToolViewModel : NavigationViewModel
{
    #region ctor
    private readonly INavItemService _navItemService;
    private readonly INavInvValuationService _navInvValuationService;
    private readonly INavInvReportClassService _navInvReportClassService;
    public NavInvValuationToolViewModel(IContainerProvider provider) : base(provider)
    {
        _navItemService = provider.Resolve<INavItemService>();
        _navInvValuationService = provider.Resolve<INavInvValuationService>();
        _navInvReportClassService = provider.Resolve<INavInvReportClassService>();

        ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

        BrowseFileCommand = new DelegateCommand(BrowseFile);
        ReadInvValuationCommand = new DelegateCommand(ReadInvValuation);
        SaveToDatabaseCommand = new DelegateCommand(SaveToDatabase);
        UpdateRoles = "admin,pur";
    }
    private string updateRoles;
    public string UpdateRoles
    {
        get => updateRoles;
        set { updateRoles = value; RaisePropertyChanged(); }
    }
    public DelegateCommand BrowseFileCommand { get; }
    public DelegateCommand ReadInvValuationCommand { get; }
    public DelegateCommand SaveToDatabaseCommand { get; }
    #endregion

    #region 属性
    private bool isEnable = true;
    public bool IsEnable
    {
        get => isEnable;
        set { isEnable = value; RaisePropertyChanged(); }
    }
    private string invValuationPath;
    public string InvValuationPath
    {
        get => invValuationPath;
        set { invValuationPath = value; RaisePropertyChanged(); }
    }
    //上个月第一天 datetime.AddDays(1 - datetime.Day).AddMonths(-1);
    //上个月的最后一天 datetime.AddDays(1 - datetime.Day).AddDays(-1);
    private DateTime lastMonth = DateTime.Today.AddDays(1 - DateTime.Today.Day).AddDays(-1);
    public DateTime LastMonth
    {
        get => lastMonth;
        set { lastMonth = value; RaisePropertyChanged(); }
    }

    private NavInvReportClassDto navInvReportClassDto ;
    public NavInvReportClassDto NavInvReportClassDto
    {
        get => navInvReportClassDto;
        set { navInvReportClassDto = value; RaisePropertyChanged(); }
    }


    //某月的第一天 datetime.AddDays(1 - datetime.Day);
    //某月的最后一天 datetime.AddDays(1 - datetime.Day).AddMonths(1).AddDays(-1);
    public ObservableRangeCollection<NavInvValuationDto> FsInvValuations { get; } = new();
    

    #endregion

    #region 读取文件
    private void BrowseFile()
    {
        var dialog = new OpenFileDialog
        {
            Filter = "Excel|*.xlsx",
            InitialDirectory = Environment.GetFolderPath(System.Environment.SpecialFolder.DesktopDirectory)
        };

        if (dialog.ShowDialog() != true) return;
        InvValuationPath=dialog.FileName;
    }
    #endregion

    #region 读取库存估值
    private async void ReadInvValuation()
    {
        IsEnable = false;
        await Task.Delay(100);

        if (string.IsNullOrEmpty(InvValuationPath))
        {
            Aggregator.SendMessage("请选择InvValuation表格地址！");
            IsEnable = true;
            return;
        }

        ChangeInvValuationTitle(InvValuationPath);

        var invValuationStrings = InvValuationPath.ReadFromExcel<List<NavInvValuationString>>();
        
        //读取物料部分
        var fsNumbers = (await _navItemService.GetAllByFsAndShareAsync()).Result.Select(x => x.Number).ToList();
        //将Number存在于navItemDtos中的取出
        FsInvValuations.ReplaceRange(invValuationStrings.Where(x => fsNumbers.Contains(x.Number)).Select(x =>
            new NavInvValuationDto
            {
                Number = x.Number,
                //再次使用当月最后一天
                YearMonth = LastMonth.AddDays(1 - LastMonth.Day).AddMonths(1).AddDays(-1),
                IncreaseQuantity = Math.Round(x.IncreaseQuantity.ToDouble(),2),
                IncreaseValue = Math.Round(x.IncreaseValue.ToDouble(), 2),
                DecreasesQuantity =Math.Round(x.DecreasesQuantity.ToDouble(), 2),
                DecreasesValue = Math.Round(x.DecreasesValue.ToDouble(), 2),
                LastValue = Math.Round(x.LastValue.ToDouble(), 2)
            }
        ));

        //读取库存类别汇总数据NavInvReportClass
        //YearMonth = LastMonth.AddDays(1 - LastMonth.Day).AddMonths(1).AddDays(-1),
        //统计原材料和半成品
        //Number为1、2开头的，RawMaterial
        var rawMtlValue = Math.Round(FsInvValuations.Where(x => x.Number[..1]=="1" || x.Number[..1]== "2").Sum(x => x.LastValue), 2);
        //Number为5、7开头的，SemiProduct
        var semiProdValue = Math.Round(FsInvValuations.Where(x => x.Number[..1]=="5" || x.Number[..1]== "7").Sum(x => x.LastValue), 2);

        //读取成品部分，统计一个库存金额总数，存储结果Sum(LastValue)
        //Number为FS开头的，FinishedGoodsTrade
        var fgTradeValue = Math.Round(invValuationStrings.Where(x => 
            x.Number[..1] == "F")
            .Select(x=>
                new NavInvValuationDto 
                    { LastValue = x.LastValue.ToDouble() })
            .Sum(x=>x.LastValue), 2);

        var fsSubTotal = rawMtlValue + semiProdValue+fgTradeValue;

        //todo:读取消耗趋势汇总数据ConsTrend包含在NavInvReportClass中
        //YearMonth = LastMonth.AddDays(1 - LastMonth.Day).AddMonths(1).AddDays(-1),
        var recvValue = Math.Round(FsInvValuations.Sum(x => x.IncreaseValue), 2);
        var consValue = Math.Round(FsInvValuations.Sum(x => x.DecreasesValue), 2);
        var gap = Math.Round(recvValue - consValue,2);

        //cons需要使用12月平均来计算，因此此处不计算MTPT
        //var totalMTPT = (int)Math.Ceiling(30d * (rmInvValue + spInvValue) / totalCons);

        NavInvReportClassDto = new NavInvReportClassDto
        {
            YearMonth = LastMonth.AddDays(1 - LastMonth.Day).AddMonths(1).AddDays(-1),
            RawMtlValue = rawMtlValue,
            SemiProdValue = semiProdValue,
            FgTradeValue = fgTradeValue,
            FsSubtotal = fsSubTotal,
            RecvValue = recvValue,
            ConsValue = consValue,
            Gap = gap
        };

        Aggregator.SendMessage("已读取InvValuation表格信息！");
        IsEnable = true;
    }

    private void ChangeInvValuationTitle(string path)
    {
        using var package = new ExcelPackage(path);
        var worksheet = package.Workbook.Worksheets[0];//第一张表格

        //数据清理：判断单元格的值，删除行
        //①，删除前11行
        if (worksheet.Cells[1, 1].Value.ToString() == "Inventory Valuation")
        {

            worksheet.DeleteRow(1, 11);
        }
        //②，遍历表格，删除无用的行(description,第二列)
        var totalRows = worksheet.Dimension.End.Row;
        for (var i = 1; i < totalRows+1; i++)
        {
            if (worksheet.Cells[i, 2].Value==null || string.IsNullOrEmpty(worksheet.Cells[i, 2].Value.ToString()))
            {
                worksheet.DeleteRow(i);
                i--;
                totalRows -= 1;
            }
        }
        //③取消筛选，取消合并单元格，否则读取的数据会错位
        worksheet.Cells[worksheet.Dimension.Address].AutoFilter=false;
        worksheet.Cells["A1:AC1"].Merge = false;

        //④，重命名表头，使用的值也命名一下，否则读取的数据会错位
        worksheet.Cells["A1"].Value = "Number";
        worksheet.Cells["B1"].Value = "Description";
        worksheet.Cells["C1"].Value = "Unit";
        worksheet.Cells["D1"].Value = "BU";
        worksheet.Cells["E1"].Value = "X1";
        worksheet.Cells["F1"].Value = "X2";
        worksheet.Cells["G1"].Value = "FirstQuantity";
        worksheet.Cells["H1"].Value = "FirstValue";
        worksheet.Cells["I1"].Value = "IncreaseQuantity";
        worksheet.Cells["J1"].Value = "IncreaseValue";
        worksheet.Cells["K1"].Value = "DecreasesQuantity";
        worksheet.Cells["L1"].Value = "DecreasesValue";
        worksheet.Cells["M1"].Value = "X3";
        worksheet.Cells["N1"].Value = "LastQuantity";
        worksheet.Cells["O1"].Value = "LastValue";
        worksheet.Cells["P1"].Value = "CostPostedToGL";
        worksheet.Cells["Q1"].Value = "X4";
        worksheet.Cells["R1"].Value = "X5";
        worksheet.Cells["S1"].Value = "MainCost";
        worksheet.Cells["T1"].Value = "X6";
        worksheet.Cells["U1"].Value = "MainValue";
        worksheet.Cells["V1"].Value = "X7";
        worksheet.Cells["W1"].Value = "X8";
        worksheet.Cells["X1"].Value = "X9";
        worksheet.Cells["Y1"].Value = "X10";
        worksheet.Cells["Z1"].Value = "WsCost";
        worksheet.Cells["AA1"].Value = "WsValue";
        worksheet.Cells["AB1"].Value = "SbuCost";
        worksheet.Cells["AC1"].Value = "SbuValue";
        //把一些重复的表头重命名一下，放置读取数据出错

        package.Save();
    }
    #endregion

    #region 保存库存估值到数据库
    private async void SaveToDatabase()
    {
        IsEnable = false;
        await Task.Delay(100);

        if (FsInvValuations.Count==0)
        {
            Aggregator.SendMessage("请先读取InvValuation表格信息，再保存到数据库！");
            IsEnable = true;
            return;
        }

        //保存询问
        var dialogResult = await DialogHost.Question("日期确认", $"确认保存数据的月份是：{FsInvValuations[0].YearMonth.Year}年{FsInvValuations[0].YearMonth.Month}月吗?");
        if (dialogResult.Result != ButtonResult.OK)
        {
            IsEnable = true;
            return;
        }


        foreach (var item in FsInvValuations)
        {
            var exist = await _navInvValuationService.GetSingleByNumberAndMonthAsync(item.Number, item.YearMonth);
            if (exist.Status)
            {
                await _navInvValuationService.UpdateAsync(exist.Result.Id.Value, item);
            }
            else
            {
                await _navInvValuationService.AddAsync(item);
            }
        }
        FsInvValuations.Clear();

        //存储库存类别汇总数据NavInvReportClass，判断如果存在就更新，否则添加
        var month = LastMonth.AddDays(1 - LastMonth.Day).AddMonths(1).AddDays(-1);
        var existReport = await _navInvReportClassService.GetSingleByMonthAsync(month);
        if (existReport.Status)
        {
            var dto = existReport.Result;
            NavInvReportClassDto.MTPT = dto.MTPT;//此处不要修改掉MTPT
            await _navInvReportClassService.UpdateAsync(dto.Id.Value, NavInvReportClassDto);
        }
        else
        {
            await _navInvReportClassService.AddAsync(NavInvReportClassDto);
        }

        Aggregator.SendMessage("已将InvValuation表格信息更新到数据库！");
        IsEnable = true;
        //跳转到MonthlyConsRecvToolView
        RegionManager.Regions[PrismManager.MainViewRegionName].RequestNavigate(nameof(NavMonthlyConsRecvToolView), back =>
        {
            Journal = back.Context.NavigationService.Journal;
        });
    }
    #endregion
}